package handler

import (
	"admin-nexus-backend/internal/dto"
	"admin-nexus-backend/internal/middleware"
	"admin-nexus-backend/internal/service"
	"admin-nexus-backend/pkg/logger"
	"admin-nexus-backend/pkg/response"
	"strconv"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// PermissionHandler 权限管理处理器
type PermissionHandler struct {
	permissionCacheService *service.PermissionCacheService
	permissionLogService   *service.PermissionLogService
	userService            *service.UserService
}

// NewPermissionHandler 创建权限管理处理器
func NewPermissionHandler(
	permissionCacheService *service.PermissionCacheService,
	permissionLogService *service.PermissionLogService,
	userService *service.UserService,
) *PermissionHandler {
	return &PermissionHandler{
		permissionCacheService: permissionCacheService,
		permissionLogService:   permissionLogService,
		userService:            userService,
	}
}

// ClearPermissionCache 清除权限缓存
// @Summary 清除权限缓存
// @Description 清除指定用户或所有用户的权限缓存
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param request body dto.ClearCacheRequest true "清除缓存请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/cache/clear [post]
// @Security Bearer
func (h *PermissionHandler) ClearPermissionCache(c *gin.Context) {
	var req dto.ClearCacheRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "参数错误: "+err.Error())
		return
	}

	// 记录操作人信息
	operatorID := middleware.GetUserID(c)
	username, _ := c.Get("username")
	operatorName := ""
	if username != nil {
		operatorName = username.(string)
	}

	var err error
	switch req.Type {
	case "user":
		if len(req.UserIDs) == 0 {
			response.BadRequest(c, "用户ID列表不能为空")
			return
		}
		err = h.permissionCacheService.ClearUsersCaches(req.UserIDs)

		// 记录日志
		for _, userID := range req.UserIDs {
			h.permissionLogService.LogPermissionChange(service.PermissionLogParams{
				UserID:       userID,
				ActionType:   "CHANGE",
				Module:       "permission_cache",
				Method:       c.Request.Method,
				Path:         c.Request.URL.Path,
				IP:           c.ClientIP(),
				UserAgent:    c.Request.UserAgent(),
				OperatorID:   operatorID,
				OperatorName: operatorName,
				Remark:       "清除用户权限缓存",
			})
		}

	case "all":
		err = h.permissionCacheService.ClearAllPermissionCache()

		// 记录日志
		h.permissionLogService.LogPermissionChange(service.PermissionLogParams{
			UserID:       operatorID,
			Username:     operatorName,
			ActionType:   "CHANGE",
			Module:       "permission_cache",
			Method:       c.Request.Method,
			Path:         c.Request.URL.Path,
			IP:           c.ClientIP(),
			UserAgent:    c.Request.UserAgent(),
			OperatorID:   operatorID,
			OperatorName: operatorName,
			Remark:       "清除所有权限缓存",
		})

	default:
		response.BadRequest(c, "不支持的缓存类型")
		return
	}

	if err != nil {
		logger.Error("清除权限缓存失败", zap.Error(err), zap.String("type", req.Type))
		response.InternalServerError(c, "清除权限缓存失败")
		return
	}

	response.SuccessWithMessage(c, "清除权限缓存成功")
}

// GetCacheStats 获取缓存统计
// @Summary 获取缓存统计
// @Description 获取权限缓存统计信息
// @Tags 权限管理
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/cache/stats [get]
// @Security Bearer
func (h *PermissionHandler) GetCacheStats(c *gin.Context) {
	stats, err := h.permissionCacheService.GetCacheStats()
	if err != nil {
		logger.Error("获取缓存统计失败", zap.Error(err))
		response.InternalServerError(c, "获取缓存统计失败")
		return
	}

	response.SuccessWithData(c, stats)
}

// GetPermissionLogs 获取权限日志列表
// @Summary 获取权限日志列表
// @Description 分页查询权限日志
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param query query dto.PermissionLogQueryParams true "查询参数"
// @Success 200 {object} response.Response{data=dto.PageResult}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/logs [get]
// @Security Bearer
func (h *PermissionHandler) GetPermissionLogs(c *gin.Context) {
	var params dto.PermissionLogQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		response.BadRequest(c, "参数错误: "+err.Error())
		return
	}

	result, err := h.permissionLogService.GetPermissionLogs(&params)
	if err != nil {
		logger.Error("获取权限日志失败", zap.Error(err))
		response.InternalServerError(c, "获取权限日志失败")
		return
	}

	response.SuccessWithData(c, result)
}

// GetPermissionLogStats 获取权限日志统计
// @Summary 获取权限日志统计
// @Description 获取指定天数的权限日志统计信息
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param days query int false "统计天数" default(7)
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/logs/stats [get]
// @Security Bearer
func (h *PermissionHandler) GetPermissionLogStats(c *gin.Context) {
	daysStr := c.DefaultQuery("days", "7")
	days, err := strconv.Atoi(daysStr)
	if err != nil || days < 1 {
		days = 7
	}

	stats, err := h.permissionLogService.GetPermissionLogStats(days)
	if err != nil {
		logger.Error("获取权限日志统计失败", zap.Error(err))
		response.InternalServerError(c, "获取权限日志统计失败")
		return
	}

	response.SuccessWithData(c, stats)
}

// CleanOldLogs 清理旧日志
// @Summary 清理旧日志
// @Description 清理指定天数之前的权限日志
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param days query int false "保留天数" default(90)
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/logs/clean [post]
// @Security Bearer
func (h *PermissionHandler) CleanOldLogs(c *gin.Context) {
	daysStr := c.DefaultQuery("days", "90")
	days, err := strconv.Atoi(daysStr)
	if err != nil || days < 1 {
		response.BadRequest(c, "保留天数必须大于0")
		return
	}

	deletedCount, err := h.permissionLogService.CleanOldLogs(days)
	if err != nil {
		logger.Error("清理旧日志失败", zap.Error(err))
		response.InternalServerError(c, "清理旧日志失败")
		return
	}

	// 记录操作日志
	operatorID := middleware.GetUserID(c)
	username, _ := c.Get("username")
	operatorName := ""
	if username != nil {
		operatorName = username.(string)
	}

	h.permissionLogService.LogPermissionChange(service.PermissionLogParams{
		UserID:       operatorID,
		Username:     operatorName,
		ActionType:   "CHANGE",
		Module:       "permission_log",
		Method:       c.Request.Method,
		Path:         c.Request.URL.Path,
		IP:           c.ClientIP(),
		UserAgent:    c.Request.UserAgent(),
		OperatorID:   operatorID,
		OperatorName: operatorName,
		Remark:       "清理权限日志",
		OldValue:     map[string]interface{}{"deletedCount": deletedCount, "keepDays": days},
	})

	response.SuccessWithData(c, map[string]interface{}{
		"deletedCount": deletedCount,
		"keepDays":     days,
	})
}

// CheckPermission 检查权限
// @Summary 检查权限
// @Description 检查用户是否拥有指定权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param request body dto.PermissionCheckRequest true "权限检查请求"
// @Success 200 {object} response.Response{data=dto.PermissionCheckResponse}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/check [post]
// @Security Bearer
func (h *PermissionHandler) CheckPermission(c *gin.Context) {
	var req dto.PermissionCheckRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "参数错误: "+err.Error())
		return
	}

	// 获取用户权限
	permissions, err := h.userService.GetUserPermissions(req.UserID)
	if err != nil {
		logger.Error("获取用户权限失败", zap.Error(err), zap.Uint("userID", req.UserID))
		response.InternalServerError(c, "获取用户权限失败")
		return
	}

	// 检查权限
	hasPermission := false
	for _, perm := range permissions {
		if perm == req.PermissionCode {
			hasPermission = true
			break
		}
	}

	result := dto.PermissionCheckResponse{
		HasPermission: hasPermission,
	}

	if !hasPermission {
		result.Reason = "用户无此权限"
	}

	response.SuccessWithData(c, result)
}

// GetUserPermissionHistory 获取用户权限变更历史
// @Summary 获取用户权限变更历史
// @Description 获取指定用户的权限变更历史记录
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param userId path int true "用户ID"
// @Param limit query int false "限制数量" default(20)
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/permissions/users/{userId}/history [get]
// @Security Bearer
func (h *PermissionHandler) GetUserPermissionHistory(c *gin.Context) {
	userIDStr := c.Param("userId")
	userID, err := strconv.ParseUint(userIDStr, 10, 32)
	if err != nil {
		response.BadRequest(c, "用户ID格式错误")
		return
	}

	limitStr := c.DefaultQuery("limit", "20")
	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit < 1 {
		limit = 20
	}

	history, err := h.permissionLogService.GetUserPermissionHistory(uint(userID), limit)
	if err != nil {
		logger.Error("获取用户权限历史失败", zap.Error(err), zap.Uint64("userID", userID))
		response.InternalServerError(c, "获取权限历史失败")
		return
	}

	response.SuccessWithData(c, history)
}
